package devicelogic

import (
	"context"

	"go-zero-admin/apps/modules/iot/cmd/rpc/internal/svc"
	"go-zero-admin/apps/modules/iot/cmd/rpc/iotpb"
	"go-zero-admin/pkg/constant"

	"github.com/zeromicro/go-zero/core/fx"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/mr"
)

type GetDeviceStateCensusLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
	getDeviceListLogic *GetDeviceListLogic
}

func NewGetDeviceStateCensusLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetDeviceStateCensusLogic {
	return &GetDeviceStateCensusLogic{
		ctx:                ctx,
		svcCtx:             svcCtx,
		Logger:             logx.WithContext(ctx),
		getDeviceListLogic: NewGetDeviceListLogic(ctx, svcCtx),
	}
}

func (l *GetDeviceStateCensusLogic) GetDeviceStateCensus(in *iotpb.GetDeviceStateCensusReq) (*iotpb.GetDeviceStateCensusResp, error) {
	listResp, err := l.getDeviceListLogic.GetDeviceList(&iotpb.GetDeviceListReq{
		IsDataScope:     in.GetIsDataScope(),
		DataScopeUserId: in.GetDataScopeUserId(),
	})
	if err != nil {
		return nil, err
	}
	list := listResp.GetList()

	// 处理数据
	var deviceOnline []int64
	var deviceOffline []int64

	err = mr.Finish(func() (err error) {
		fx.From(func(source chan<- interface{}) {
			for _, v := range list {
				source <- v
			}
		}).Filter(func(item interface{}) bool {
			iotDevice := item.(*iotpb.IotDevice)
			if iotDevice.GetState() == constant.DeviceStateOn {
				return true
			}
			return false
		}).ForEach(func(item interface{}) {
			device := item.(*iotpb.IotDevice)
			deviceOnline = append(deviceOnline, device.GetId())
		})
		return
	}, func() (err error) {
		fx.From(func(source chan<- interface{}) {
			for _, v := range list {
				source <- v
			}
		}).Filter(func(item interface{}) bool {
			iotDevice := item.(*iotpb.IotDevice)
			if iotDevice.GetState() == constant.DeviceStateOff {
				return true
			}
			return false
		}).ForEach(func(item interface{}) {
			device := item.(*iotpb.IotDevice)
			deviceOffline = append(deviceOffline, device.GetId())
		})
		return
	})

	return &iotpb.GetDeviceStateCensusResp{
		Devices:       int64(len(list)),
		DeviceOnline:  int64(len(deviceOnline)),
		DeviceOffline: int64(len(deviceOffline)),
	}, nil
}
